package com.seo.service.sms.impl;

import java.util.Date;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.http.FormatType;
import com.seo.mapper.sms.SmsCodeMapper;
import com.seo.pojo.ReturnBody;
import com.seo.pojo.SmsTemplet;
import com.seo.service.sms.sdk.SmsCodeService;
import com.seo.utils.CustomUtil;
import com.seo.utils.DateUtil;
import com.seo.utils.SmsUtil;

import cn.hutool.json.JSONObject;
import lombok.extern.slf4j.Slf4j;

/**
 * 短信service
 * 
 * @author Administrator
 * @version 2018.08.02 17:40
 */
@Slf4j
@Service("smsCodeService")
public class SmsCodeServiceImpl implements SmsCodeService {

	@Autowired
	private SmsCodeMapper smsCodeMapper;

	@Transactional
	@Override
	public ReturnBody sendSmsCode(Map<String, Object> params) {
		ReturnBody rb = ReturnBody.init();
		try {

			String type = (String) params.get("type");
			SmsTemplet st = smsCodeMapper.getSmsTempletByCode(type);
			if (st == null) {
				return rb.error("服务未开通");
			}

			Map<String, Object> validate = smsCodeMapper.getSmsData(params);
			if (validate == null) {
				params.put("expireTime", "600");
				params.put("code", CustomUtil.buildRandom(6) + "");
				params.put("sendNum", 1);
				rb.run(saveSendDB(params, st, true));
				if (!rb.isSuccess()) {
					return rb.setRollback();
				}
				return rb;
			}
			Date createTime = DateUtil.fomatDateTime((String) validate.get("createTime"), "yyyy-MM-dd HH:mm:ss");

			int days = DateUtil.daysOfTwo(createTime, new Date());
			if (days != 0) {
				validate.put("sendNum", 0);
				smsCodeMapper.intiSmsData(validate);
				params.put("expireTime", "600");
				params.put("code", CustomUtil.buildRandom(6) + "");
				rb.run(saveSendDB(params, st, false));
				if (!rb.isSuccess()) {
					return rb.setRollback();
				}
				return rb;
			}
			int sendNum = (int) validate.get("sendNum");
			if (sendNum > 10) {
				return rb.rollback("获取验证码已经达到上限请在次日后再试");
			}
			if (sendNum < 3) {
				params.put("expireTime", "600");
				params.put("code", CustomUtil.buildRandom(6) + "");
				rb.run(saveSendDB(params, st, false));
				if (!rb.isSuccess()) {
					return rb.setRollback();
				}
				return rb;
			}
			long now = System.currentTimeMillis();
			long dates = Long.valueOf(DateUtil.dateToStamp((String) validate.get("createTime"))).longValue();
			if (sendNum >= 3 && ((now / 1000) - (dates / 1000)) > 900) {
				params.put("expireTime", "600");
				params.put("code", CustomUtil.buildRandom(6) + "");
				rb.run(saveSendDB(params, st, false));
				if (!rb.isSuccess()) {
					return rb.setRollback();
				}
				return rb;
			}
			return rb.rollback("请求次数过于频繁,请15分钟后重发");
		} catch (Exception e) {
			log.error("异常-[{}]", e);
			return rb.rollback("发送失败");
		} finally {
			rb.result();
		}
	}

	private ReturnBody saveSendDB(Map<String, Object> sms, SmsTemplet st, Boolean o) {
		ReturnBody rb = ReturnBody.init();
		try {
			int i = 0;
			if (o) {
				sms.put("isUse", "00");
				i = smsCodeMapper.saveSmsCode(sms);
			} else {
				sms.put("isUse", "00");
				i = smsCodeMapper.updateSmsCode(sms);
			}
			if (i >= 1) {
				String code = (String) sms.get("code");
				String phone = (String) sms.get("phone");
				SendSmsRequest request = new SendSmsRequest();
				JSONObject jsonCode = new JSONObject();
				if (!StringUtils.isEmpty(code)) {
					jsonCode.accumulate("code", code);
					request.setTemplateParam(jsonCode.toString());
				}
				request.setPhoneNumbers(phone);
				request.setAcceptFormat(FormatType.JSON);
				return SmsUtil.sendCode(request, st);
			}
			return rb.error("发送失败");
		} catch (Exception e) {
			log.error("发送失败-异常-[{}]", e);
			return rb.error("发送失败");
		}
	}

	@Override
	public ReturnBody updateValidateCode(Map<String, Object> param) {
		ReturnBody rb = ReturnBody.init();
		try {
			Map<String, Object> validate = smsCodeMapper.getSmsData(param);
			if (validate == null) {
				return rb.error("not_exists", "验证码不存在!");
			}
			String code = (String) validate.get("code");
			String pcode = (String) param.get("code");
			if (!code.equals(pcode)) {
				return rb.error("code_error", "验证码错误!");
			}
			if ("01".equals(validate.get("isUse"))) {
				return rb.error("code_use", "验证码已使用!");
			}
			String time = (String) validate.get("expireTime");
			long lose = Long.parseLong(time);

			Long newTime = System.currentTimeMillis();
			if (lose < (newTime / 1000)) {
				return rb.error("code_expire", "验证码已失效!");
			}
			validate.put("isUse", "01");
			int num = smsCodeMapper.upudateIsSue(validate);
			if (num == 0) {
				return rb.error("error", "校验失败!");
			} else {
				return rb.success("ok", "验证通过!");
			}
		} catch (Exception e) {
			return rb.error("error", "校验失败!");
		}
	}

}
